package cn.edu.jxau.core.util.upload;

import cn.edu.jxau.core.controller.CoreServlet;
import cn.edu.jxau.core.util.StringUtil;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 文件上传
 * <p>
 * MangoDai 2017 08 23 3:08 PM
 */
public class FileUpload {
	private static Logger logger = LoggerFactory.getLogger(FileUpload.class);
	private static final int SIZETHRESHOLD = 1<< 18; // 缓存区大小
	private static final int FILEMAXSIZE = 1 << 18; // 文件最大大小 7
	private static final String[] extensionPermit = { "txt", "jar", "pdf", "png", "jpg" }; // 允许上传的扩展名
	public static final String BASEPATH = "/upload/data"; // 上传的地址
	public static final String SWAPPATH = "/upload/data/swap"; // 上传的地址
	public static final String SPECTRUMPATH = "/upload/data/spectrum";
	public static final String IMAGEPATH = "/upload/data/image";
	public static final String SEPERATOR = "-.-"; // 文件分隔符

	private static String webRootPath = null;

	public static File getFile(String path) {
		File file = new File(getBaseABSPath(), path);
		if (file.exists() && file.isFile()) {
			return file;
		}
		return null;
	}

	/**
	 * 保存文件
	 *
	 * @param request
	 *            请求
	 * @param path
	 *            保存路径，请使用静态常量，或者基础+自定义
	 * @param results
	 * @return 返回文件数组
	 */
	public File[] doSava(HttpServletRequest request, String path, Map<String, Object[]> results) {
		String save = getBaseABSPath() + path + StringUtil.dateConfound();
		File savePath = new File(save);
		ArrayList<File> files = new ArrayList<>();
		if (!savePath.exists()) {
			savePath.mkdirs();// 文件夹不存在，就创建
		}
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setRepository(savePath); // 保存路径
		ServletFileUpload upload = new ServletFileUpload(factory);
		FileProcessListener processListener = new FileProcessListener(request.getSession());
		upload.setProgressListener(processListener); // 上传监听
		upload.setFileSizeMax(FILEMAXSIZE);
		upload.setHeaderEncoding(CoreServlet.ENCODING);
		try {
			List<FileItem> fileItems = upload.parseRequest(request); // 开始处理
			for (FileItem fileItem : fileItems) {
				String fieldName = fileItem.getFieldName();
				String fileName = fileItem.getName();
				// 如果为上传文件数据
				if (!fileItem.isFormField()) {
					logger.debug("fieldName[" + fieldName + "] fileName[" + fileName + "] ");
					if (fileItem.getSize() > 0) {
						String fileExtension = FilenameUtils.getExtension(fileName);
						if (!ArrayUtils.contains(extensionPermit, fileExtension)) {
							throw new NullPointerException("No Support extension.");
						}
						String name = StringUtil.getUUID() + SEPERATOR + FilenameUtils.getName(fileName);
						File tmp = new File(savePath, name);
						FileUtils.copyInputStreamToFile(fileItem.getInputStream(), tmp);
						files.add(tmp);
					}
				} else {
					String value = fileItem.getString(CoreServlet.ENCODING);
					String[] values = new String[1];
					values[0] = value;
					results.put(fieldName, values);
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return files.toArray(new File[files.size()]);
	}

	/**
	 * 得到项目根路径
	 *
	 * @return
	 */
	public static String getBaseABSPath() {
		if (webRootPath == null) {
			URL resource = FileUpload.class.getClassLoader().getResource("/");
			String str = null;
			try {
				str = URLDecoder.decode(resource.getPath(),"UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			File file = new File(str);
			webRootPath = file.getParentFile().getParentFile().getAbsolutePath();
		}
		return webRootPath;
	}

	/**
	 * 快速移动文件 目的路径会加上项目的
	 *
	 * @param source
	 *            源文件
	 * @param path
	 *            目的路径
	 * @return
	 */
	public static boolean velocityMove(File source, String path) {
		File target = new File(getBaseABSPath(), path + StringUtil.dateConfound());
		if (!target.exists())
			target.mkdirs();
		File targetFile = new File(target, source.getName());
		try (InputStream fis = new BufferedInputStream(new FileInputStream(source));
				OutputStream fos = new BufferedOutputStream(new FileOutputStream(targetFile));) {
			byte[] buf = new byte[4096];
			int i;
			while ((i = fis.read(buf)) != -1) {
				fos.write(buf, 0, i);
			}
			logger.debug("文件已经被移动了 source: " + source.getAbsolutePath() + " target: " + targetFile.getAbsolutePath());
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
}
